/*

 * Copyright (C) 2021 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */
package com.chinalwb.are.utils;


import com.chinalwb.are.view.RichTextView;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.Text;
import ohos.agp.text.*;
import ohos.agp.utils.TextTool;

import java.util.*;

/**
 * 富文本样式封装类
 *
 * @since 2021/06/22
 */
public class TextDecorator {
    /**
     * UNDERLINE
     */
    public static final int UNDERLINE = 1;
    /**
     * TEXT_COLOR
     */
    public static final int TEXT_COLOR = 2;
    /**
     * TEXT_BAG
     */
    public static final int TEXT_BAG = 3;
    /**
     * STRIKETHROUGH
     */
    public static final int STRIKETHROUGH = 4;
    /**
     * SUBSCRIPT
     */
    public static final int SUBSCRIPT = 5;
    /**
     * SUBSCRIPT
     */
    public static final int SUPERSCRIPT = 6;
    /**
     * ABSOLUTE_SIZE
     */
    public static final int ABSOLUTE_SIZE = 8;
    /**
     * TEXT_MINIFY
     */
    public static final int TEXT_MINIFY = 10;
    /**
     * TEXT_SCALE
     */
    public static final int TEXT_SCALE = 11;
    /**
     * 设置字体斜体
     */
    public static final int TYPE_ITALIC = 1001;
    /**
     * 设置字体加粗
     */
    public static final int TYPE_BOLD = 1002;
    /**
     * sTextDecorator
     */
    public static volatile TextDecorator sTextDecorator;
    /**
     * 文本控件
     */
    private Text textView;
    /**
     * 文本内容
     */
    private String content;

    /**
     * 字符串所在下标 集合
     */
    private List<Integer> indexList;
    /**
     * 下标 字符串 键值对 集合
     */
    private Map<Integer, String> indexTextMap;
    /**
     * 下标 富文本对象 键值对 集合
     */
    private Map<Integer, TextForm> indexTextFormMap;

    private RichTextBuilder richTextBuilder;
    /**
     * 当前光标位置
     */
    private int currentCursor;
    private StateBean stateBean;

    /**
     * 单例
     *
     * @return TextDecorator
     */
    public static TextDecorator getInstance() {
        if (sTextDecorator == null) {
            synchronized (TextDecorator.class) {
                if (sTextDecorator == null) {
                    sTextDecorator = new TextDecorator();
                }
            }
        }
        return sTextDecorator;
    }

    private void setView(Text textView, String content) {
        this.textView = textView;
        this.content = content;
        indexList = new ArrayList<>();
        indexTextMap = new HashMap<>();
        indexTextFormMap = new HashMap<>();
        richTextBuilder = new RichTextBuilder();
    }

    /**
     * 创建富文本对象显示设置的文本相关样式
     */
    private void build() {
        int count = 0;
        for (int i = 0; i < content.length(); i++) {
            richTextBuilder.mergeForm(indexTextFormMap.get(indexList.get(count)));
            richTextBuilder.addText(indexTextMap.get(indexList.get(count)));
            richTextBuilder.revertForm();
            count++;
        }
        RichText richText = richTextBuilder.build();
        if (textView instanceof RichTextView) {
            RichTextView richTextView = (RichTextView) this.textView;
            richTextView.setContent(richText);
        } else {
            textView.setRichText(richText);
        }
    }

    /**
     * 显示
     */
    private void show() {
        indexList.clear();
        for (int i = 0; i < content.length(); i++) {
            indexList.add(i);
            indexTextMap.put(i, String.valueOf(content.charAt(i)));
            setTextForm(i, stateMap.get(i));
        }
        build();
    }

    private void setTextForm(int position, StateBean stateBean) {
        TextForm textForm = new TextForm();
        if (stateBean != null && stateBean.getStyleMap() != null && stateBean.getStyleMap().size() > 0) {
            Set<Integer> values = stateBean.getStyleMap().keySet();
            for (Integer value : values) {
                setStyle(stateBean, value, textForm, position, stateBean.getStyleMap());
            }
        } else {
            setStyle(stateBean, -1, textForm, position, null);
        }
    }


    private void setStyle(StateBean stateBean, int style, TextForm textForm,
                          int position, Map<Integer, Boolean> styleMap) {
        switch (style) {
            case UNDERLINE:
                indexTextFormMap.put(position, textForm.setUnderline(styleMap.get(UNDERLINE)));
                break;
            case TEXT_COLOR:
                indexTextFormMap.put(position, textForm.setTextColor(stateBean.getColor()));
                break;
            case TEXT_BAG:
                indexTextFormMap.put(position,
                        textForm.setTextBackgroundColor(stateBean.getBgColor()));
                break;
            case STRIKETHROUGH:
                indexTextFormMap.put(position, textForm.setStrikethrough(styleMap.get(STRIKETHROUGH)));
                break;
            case ABSOLUTE_SIZE:
                indexTextFormMap.put(position, textForm.setTextSize(
                        AttrHelper.fp2px(stateBean.getSize(), textView.getContext())));
                break;
            case SUPERSCRIPT:
                indexTextFormMap.put(position, textForm.setSuperscript(styleMap.get(SUPERSCRIPT)));
                break;
            case SUBSCRIPT:
                indexTextFormMap.put(position, textForm.setSubscript(styleMap.get(SUBSCRIPT)));
                break;
            case TYPE_ITALIC:
            case TYPE_BOLD:
                Font.Builder fontBuilder = new Font.Builder(String.valueOf(content.charAt(position)));
                if (styleMap.get(TYPE_ITALIC) != null && styleMap.get(TYPE_ITALIC)) {
                    fontBuilder.makeItalic(true);
                }
                if (styleMap.get(TYPE_BOLD) != null && styleMap.get(TYPE_BOLD)) {
                    fontBuilder.setWeight(Font.BOLD);
                }
                Font build = fontBuilder.build();
                indexTextFormMap.put(position, textForm.setTextFont(
                        ((styleMap.get(TYPE_ITALIC) != null && styleMap.get(TYPE_ITALIC)) || (
                                styleMap.get(TYPE_BOLD) != null && styleMap.get(TYPE_BOLD))) ? build : Font.DEFAULT));
//                indexTextFormMap.put(position, textForm.setTextFont(styleMap.get(TYPE_BOLD) ? Font.DEFAULT_BOLD : Font.DEFAULT));
                break;
            default:
                indexTextFormMap.put(position, textForm.setTextFont(Font.DEFAULT));
                break;
        }
    }

    private final Map<Integer, StateBean> stateMap = new HashMap<>();

    /**
     * 设置 文本样式
     *
     * @param stateBean 样式
     */
    public void setStateBean(StateBean stateBean) {
        this.stateBean = stateBean;
    }

    private String proText;

    /**
     * 初始化
     *
     * @param textField EDIT
     * @param tvContent TEXT
     */
    public void init(CursorTextField textField, Text tvContent) {
        stateMap.clear();
        textField.addTextObserver((text, start, before, count) -> {
            if (stateBean == null) {
                stateBean = new StateBean();
            }
            if (text.length() == currentCursor) {
                // 光标在最后
                cursorInEnd(text);
            } else {
                // 移动了光标
                if (!TextTool.isNullOrEmpty(proText) && text.length() < proText.length()) {
                    // 删除
                    cursorDelete();
                } else {
                    // 添加
                    cursorAdd(text);
                }
            }
            proText = text;
            setView(tvContent, text);
            show();
        });
        textField.setCursorChangedListener((var1, var2, var3) -> this.currentCursor = var2);
    }

    /**
     * 光标在最后
     *
     * @param text text
     */
    private void cursorInEnd(String text) {
        if ((TextTool.isNullOrEmpty(proText) && text.length() > 1)
                || (!TextTool.isNullOrEmpty(proText) && text.length() - proText.length() > 1)) {
            String substring = text.substring(TextTool.isNullOrEmpty(proText) ? 0 : proText.length());
            char[] chars = substring.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                stateMap.put(TextTool.isNullOrEmpty(proText) ? i : proText.length() + i, stateBean);
            }
        } else {
            if (TextTool.isNullOrEmpty(proText) || (proText.length() < text.length())) {
                stateMap.put(text.length() - 1, stateBean);
            }
        }
    }

    /**
     * 删除文字
     */
    private void cursorDelete() {
        stateMap.remove(currentCursor);
        Set<Integer> integers = stateMap.keySet();
        Set<Integer> integers1 = new HashSet<>(integers);
        Iterator<Integer> iterator = integers1.iterator();
        HashMap<Integer, StateBean> temp = new HashMap<>();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            if (next >= currentCursor) {
                StateBean state = stateMap.get(next);
                temp.put(next - 1, state);
            }
        }
        stateMap.putAll(temp);
    }

    /**
     * 添加文字
     *
     * @param text text
     */
    private void cursorAdd(String text) {
        int offset = (!TextTool.isNullOrEmpty(proText) && text.length() -
                proText.length() > 1) ? text.length() - proText.length() : 1;
        Set<Integer> integers = stateMap.keySet();
        Set<Integer> integers1 = new HashSet<>(integers);
        Iterator<Integer> iterator = integers1.iterator();
        HashMap<Integer, StateBean> temp = new HashMap<>();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            if (next >= currentCursor - offset) {
                StateBean bean = stateMap.get(next);
                temp.put(next + offset, bean);
            }
        }
        stateMap.putAll(temp);
        int startIndex = currentCursor - offset;
        if (startIndex < 0) {
            startIndex = 0;
        }
        String substring = text.substring(startIndex, currentCursor);
        char[] chars = substring.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            stateMap.put(startIndex + i, stateBean);
        }
    }

    /**
     * 不要输入框
     *
     * @param tvContent tvContent
     */
    public void setNoFieldStyle(Text tvContent) {
        if (!TextTool.isNullOrEmpty(content)) {
            setView(tvContent, content);
            show();
        }
    }


    /**
     * 退出页面时调用
     */
    public void release() {
        TextStyleUtils.getInstance().release();
        stateMap.clear();
        stateBean = null;
        proText = null;
        if (indexList != null) {
            indexList.clear();
        }
        if (indexTextFormMap != null) {
            indexTextFormMap.clear();
        }
        if (indexTextMap != null) {
            indexTextMap.clear();
        }
    }
}